﻿#region [ Modification History ]
/*
 * 05/29/2013 Denis Kholine
 *  Generated Original version of source code.
 */
#endregion

#region  [ UIUC NCSA Open Source License ]
/*****************************************************************************\
 *             University of Illinois/NCSA Open Source License
 *
 * 
 *      Copyright © 2012,2013, The Board of Trustees of the University of Illinois. All rights reserved.
 *
 *      Developed by: Rakesh Bobba, Derek Dagit, Erich Heine, Denis Kholine,
 *                    Klara Nahrstedt, David Rodgers,   William H. Sanders, Tim Yardley
 *
 *      Information Trust Institute/Coordinated Science Laboratory
 * 
 *      University of Illinois
 *      
 *      The Board of Trustees of the University of Illinois
 *      109 Coble Hall
 *      801 South Wright Street
 *      Champaign, IL 61820-6242
 *
 *      http://www.iti.illinois.edu / http://csl.illinois.edu
 * 
 *      Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 
 *      associated documentation files (the “Software”), to deal with the Software without restriction, 
 *      including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *      and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
 *      subject to the following conditions:
 *
 *      Redistributions of source code must retain the above copyright notice, this list of conditions and the
 *      following disclaimers.
 *      
 *      Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 *      the following disclaimers in the documentation and/or other materials provided with the distribution.
 *
 *      Neither the names of Information Trust institute, Coordinated Science Laboratory, University of Illinois,
 *      The Board of Trustees of the University of Illinois nor the names of its contributors may be used to 
 *      endorse or promote products derived from this Software without specific prior written permission.
 *      
 *      THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 *      LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN
 *      NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *      WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
 *      SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 *      
 \*****************************************************************************/
#endregion

#region [ Using plus External Dependencies see note below]
/*
 * C:\Projects\SIEGate.ITI.05202013\Main\Source\packages\QuickGraph.3.6.61119.7\lib\net4\QuickGraph.dll
 */

using System;
using SIEGate.Core;
using SIEGate.Core.Notifications;
using SIEGate.Core.MessageBusses;
using SIEGate.Core.Configurator;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using GSF.TimeSeries.Transport;
using SIEGate.Core.Fakes;
#endregion

namespace SIEGateCoreTest.Configurator
{
    
    /// <summary>
    /// A test class for ConfigGraph
    /// Test setup: N1 contains inputs and outputs counter clockwise graph
    ///  IDs used: N1A1, A1N2, N2A2, A2N3, N3A3, A3N1
    /// N1 <- A3 <-N3
    ///   \       /
    ///    A1    A2
    ///     \   /
    ///       N2
    /// </summary>
    [TestClass]
    public class ConfigGraphTests
    {
        #region [ Members ]
        // first node input output 
        private Guid input;
        private Guid output;
            
        // Assume configGraph are ready for tests
        private ConfigGraph configGraph;
        private ConfigGraph secondGraph;

        private ISet<Guid> N1inputs;
        private ISet<Guid> N1outputs;

        private ISet<Guid> N1A1;
        private ISet<Guid> A1N2;
        private ISet<Guid> N2A2;
        private ISet<Guid> A2N3;
        private ISet<Guid> N3A3;
        private ISet<Guid> A3N1; 

        private ConfigGraph graph;
        private List<IConfigInfo> simpleconfig;

        private MockDataProcessorInfo N1;
        private MockDataProcessorInfo N2;
        private MockDataProcessorInfo N3;

        private MockSmartAdapter.MockSmartAdapterInfo A1s;
        private MockSmartAdapter.MockSmartAdapterInfo A2s;
        private MockSmartAdapter.MockSmartAdapterInfo A3s;

        private IAdapterInfo A1;
        private IAdapterInfo A2;
        private IAdapterInfo A3;
        #endregion

        #region [ Methods ]
        /// <summary>
        /// Graph initialization function
        /// </summary>
        /// <param name="adapterType">AdapterType simple if true and smart if faulse</param>
        /// <returns></returns>
        public ConfigGraph InitializeSimpleGraph(bool adapterType)
        { 
            // instantiate graph
            graph = new ConfigGraph();
            simpleconfig = new List<IConfigInfo>();


            N1inputs = new HashSet<Guid>();
            N1outputs = new HashSet<Guid>();

            N1A1 = new HashSet<Guid>();
            A1N2 = new HashSet<Guid>();
            N2A2 = new HashSet<Guid>();
            A2N3 = new HashSet<Guid>();
            N3A3 = new HashSet<Guid>();
            A3N1 = new HashSet<Guid>(); 
            
            // initialize Guid's
            N1A1.Add(Guid.Parse("AF48C6FF-C415-45D9-A8B5-2F18819FEE4A"));
            A1N2.Add(Guid.Parse("A251E481-F735-453E-90B2-BED619C81E07"));
            N2A2.Add(Guid.Parse("FE321AD0-74BF-4CD4-B47A-3C02E18D16C4"));
            A2N3.Add(Guid.Parse("05AD5328-4819-48AD-BF1D-FBA918465A5D"));
            N3A3.Add(Guid.Parse("9F26BA0B-27E3-40F8-B893-D02D643AB04D"));
            A3N1.Add(Guid.Parse("8DF32F83-9E46-4D75-BDC8-FE7727D854B3"));

            // initialize input
            input = Guid.Parse("4929AD56-B209-4990-8DAC-C8927ECCEB9C");
            N1inputs.Add(input);
            N1inputs.UnionWith(A3N1);

            // initialize output
            output = Guid.Parse("9BE6DC5C-E35C-42EB-8A04-A0AF8A3F59C2");
            N1outputs.Add(output);
            N1outputs.UnionWith(N1A1); 

            // create nodes & edges
            N1 = new MockDataProcessorInfo(N1inputs, N1outputs);
            N2 = new MockDataProcessorInfo(A1N2, N2A2);
            N3 = new MockDataProcessorInfo(A2N3, N3A3);

            N1.ID = 1;
            N2.ID = 2;
            N3.ID = 3;

            simpleconfig.Add(N1);
            simpleconfig.Add(N2);
            simpleconfig.Add(N3);

            // if false smart adapter if true simple adapter
            if (adapterType == true)
            {
                A1 = new MockAdapter.MockAdapterInfo(N1A1, A1N2);
                A2 = new MockAdapter.MockAdapterInfo(N2A2, A2N3);
                A3 = new MockAdapter.MockAdapterInfo(N3A3, A3N1);

                A1.ID = 4;
                A2.ID = 5;
                A3.ID = 6;

                simpleconfig.Add(A1);
                simpleconfig.Add(A2);
                simpleconfig.Add(A3);

            }
            else
            {
                A1s = new MockSmartAdapter.MockSmartAdapterInfo(N1A1, A1N2);
                A2s = new MockSmartAdapter.MockSmartAdapterInfo(N2A2, A2N3);
                A3s = new MockSmartAdapter.MockSmartAdapterInfo(N3A3, A3N1);

                A1s.SetStaticInputs(false);
                A2s.SetStaticInputs(true);
                A3s.SetStaticInputs(false);

                A1s.ID = 4;
                A2s.ID = 5;
                A3s.ID = 6; 

                simpleconfig.Add(A1s);
                simpleconfig.Add(A2s);
                simpleconfig.Add(A3s);
            } 

            graph.Build(simpleconfig);

            return graph;
        }

        /// <summary>
        /// A ConfigGraph Collapse test
        /// </summary>
        [TestMethod]
        [TestCategory("ConfigGraph")]
        public void CollapseSmartAdaptersTest()
        {
            configGraph = InitializeSimpleGraph(false);

            configGraph.Collapse();

            List<IDataProcessorInfo> nodes = new List<IDataProcessorInfo>(configGraph.Nodes);
              
            bool expected = true;
            bool actual = nodes.Contains(N1);
            Assert.AreEqual(expected, actual);
            actual = nodes.Contains(N2);
            Assert.AreEqual(expected, actual);
            actual = nodes.Contains(N3);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// A ConfigGraph Collapse test
        /// </summary>
        [TestMethod]
        [TestCategory("ConfigGraph")]
        public void CollapseNodesAssignmentTest()
        {
            configGraph = InitializeSimpleGraph(false);
            configGraph.Collapse();

            bool expected = true;
            bool actual1 = false;
            bool actual2 = false;
            bool actual3 = false;

            try
            {
                // Contain 6 elements but exits only 3 actual nodes
                // Nodes count algorithm
                foreach (MockDataProcessorInfo node in configGraph.Nodes)
                {
                    if (node.Equals(N1))
                    {
                        actual1 = true;
                    }
                    else if (node.Equals(N2))
                    {
                        actual2 = true;
                    }
                    else if (node.Equals(N3))
                    {
                        actual3 = true; ;
                    }
                }
            }
            catch
            {
                Assert.IsTrue(false);
            }

            Assert.AreEqual(expected, actual1);
            Assert.AreEqual(expected, actual2);
            Assert.AreEqual(expected, actual3);
            
        }

        /// <summary>
        /// A ConfigGraph Collapse invocation list test
        /// </summary>
        [TestMethod]
        [TestCategory("ConfigGraph")]
        public void CollapsersInvocationListTest()
        {
            configGraph = InitializeSimpleGraph(false); 
            int expected = 1;
            int actual = configGraph.Collapsers.GetInvocationList().Length;
            Assert.AreEqual(expected, actual);
            Assert.IsInstanceOfType(configGraph.Collapsers, typeof(CollapseDelegate)); // check type
        }

        /// <summary>
        /// A ConfigGraph Provider test
        /// </summary>
        [TestMethod]
        [TestCategory("ConfigGraph")]
        public void ConfigGraphProviderTest()
        {
            configGraph = InitializeSimpleGraph(false);
            configGraph.Collapse();
            uint output;
            bool expected = true;
            bool actual = false;
            try
            {
                actual = ConfigGraph.GetProviderFor(input, out output);
            }
            catch
            {
                actual = false;
            }
            
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// A ConfigGraph Streams test
        /// </summary>
        [TestMethod]
        [TestCategory("ConfigGraph")]
        public void ConfigGraphStreamsTest()
        {
            configGraph = InitializeSimpleGraph(false);
            configGraph.Collapse();
            HashSet<Guid> streams = ConfigGraph.AllPublishableStreams();
            bool expected = false;
            bool actual = (streams.Contains(input));
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// A ConfigGraph print test
        /// </summary>
        [TestMethod]
        [TestCategory("ConfigGraph")]
        public void ConfigGraphPrintTest()
        {
            configGraph = InitializeSimpleGraph(false);
            configGraph.Collapse();
            string str = ConfigGraph.PrintGraph();
            bool expected = true;
            bool actual =(str.Length > 0 && str.Contains(input.ToString()) && str.Contains(output.ToString()));
            Assert.AreEqual(expected,actual);
        }

        #endregion
    }
}
